package com.imhere.sou.util;

import java.io.IOException;
import java.lang.reflect.Method;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

/**
 * Json工具类
 * @author linxiong.Li
 * @version 1.0 创建时间：2015年7月27日 下午8:13:44
 * @company 广州新关系科技有限公司
 *
 * 功能描述：
 */
public class JsonUtil {
	
	private static final ObjectMapper objectMapper = new ObjectMapper();
	
	/**
	 * 将json字符串转成实体对象
	 * @param json json字符串
	 * @param clazz 对象class对象
	 * @return
	 */
	public static <T> T json2Bean(String json, Class<T> clazz){
		if(StringUtil.isEmpty(json)) return null;
		T t = null;
		try {
			t = objectMapper.readValue(json, clazz);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return t;
	}
	
	/**
	 * 将对象转成json字符串
	 * @param object
	 * @return
	 */
	public static String bean2Json(Object object) {
		if(object==null) return "";
		String json = "";
		try {
			json = objectMapper.writeValueAsString(object);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return json;
	}
	
	/**
	 * 对象属性值复制
	 * @param obj 被复制的对象
	 * @param clazz 需要赋值的对象类
	 * @return
	 */
	public static <T> T copyValues(Object obj, Class<T> clazz){
		try {
			if(obj==null) return clazz.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		T t = objectMapper.convertValue(obj, clazz);
		
		return t;
	}
	
	/**
	 * 对象属性值拷贝(注：有共同的属性但被拷贝对象该属性值为null时，赋予目标对象默认值)
	 * @param fromObj 被拷贝对象
	 * @param toObj 被赋值对象
	 */
	public static void copyValuesFromObj(Object fromObj, Object toObj){
		//获取被拷贝对象声明的所有方法
		Method[] fromMethods = fromObj.getClass().getDeclaredMethods();
		//获取目标对象声明的所有方法
		Method[] toMethods = toObj.getClass().getDeclaredMethods();
		Method getMethod = null;
		for (Method method : toMethods) {
			//获取方法名
			String methodName = method.getName();
			//忽略不是以set开头的方法
			if(!methodName.startsWith("set")) continue;
			//获取该set方法对应的get方法
			String getMethodName = "get" + methodName.substring(3);
			//找到被拷贝对象的get方法
			for (Method fromMethod : fromMethods) {
				if(getMethodName.equals(fromMethod.getName())) {
					getMethod = fromMethod;
					break;
				}
			}
			//找不到get方法，忽略
			if(getMethod==null) continue;
			try {
				//调用被拷贝对象的get方法获取值
				Object object = getMethod.invoke(fromObj, new Object[0]);
				if(object==null) {
					if(Long.class==getMethod.getReturnType()) object = -1L;
					if(String.class==getMethod.getReturnType()) object = "";
					if(Integer.class==getMethod.getReturnType()) object = -1;
				}
				//调用目标对象的set方法赋值
				method.invoke(toObj, new Object[]{object});
			} catch (Exception e) {
				continue;
			}
		}
	}
}
